package com.chengliang.bbs.util;
import com.alibaba.fastjson.JSONObject;
import com.chengliang.bbs.entry.User;
import com.chengliang.bbs.entry.UserAuths;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author: chengliang
 * @create: 2019-07-28 14:12
 */
@Component
@Slf4j
public class QQUtils {

    @Value("${qq.client-id}")
    private  String appId;

    @Value("${qq.client-key}")
    private  String appKey;

    @Value("${qq.call-url}")
    private  String callUrl;

    /**
     * 指定map获取用户信息的key值
     * 昵称
     */
    private final static String NICK_NAME_KEY = "nickName";
    /**
     * 性别 男 或 女
     */
    private final static String GENDER_KEY ="gender";
    /**
     * 头像 完整URL路径
     */
    private final static String AVATAR_KEY ="avatar";

    /**
     * state存储session的key名
     */
    private final static String STATE_KEY="state";

    /**
     * 获取qq登录地址，并生成code
     * @param session
     * @return
     */
    public  String getQQLoginUrl(HttpSession session){
        String state = UUID.randomUUID().toString();
        session.setAttribute(STATE_KEY,state);
        StringBuffer url=new StringBuffer()
                .append("redirect:https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=")
                .append(appId)
                .append("&redirect_uri=").append(callUrl)
                .append("&state="+state);
        return url.toString();
    }

    /**
     * 效验qq返回的state是否正确
     * @param state 服务端生成的state
     * @param session session会话对象
     * @return
     */
    public boolean checkState(String state,HttpSession session){
        if(StringUtil.isEmpty(state)){
            return false;
        }
        if(!state.equals(session.getAttribute(STATE_KEY))){
            return false;
        }
        return true;
    }


    /**
     * 通过code获取token信息
     * @param code code
     * @return token字符串
     */
    public String getTokenByCode(String code){
        if(StringUtil.isEmpty(code)){
            return null;
        }
        //使用临时code 获取token值
        String url=new StringBuffer().append("https://graph.qq.com/oauth2.0/token?grant_type=authorization_code")
                .append("&client_id=").append(appId)
                .append("&client_secret=").append(appKey)
                .append("&code=").append(code)
                .append("&redirect_uri=").append(callUrl)
                .toString();
        try {
            String responseText = Jsoup.connect(url).get().body().text();
            return parseStringGetToken(responseText);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 根据token获取openId
     * @param token token信息
     * @return
     */
    public String getOpenIdByToken(String token){
        if(StringUtil.isEmpty(token)){
            return null;
        }
        String url=new StringBuilder().append("https://graph.qq.com/oauth2.0/me")
                .append("?access_token=").append(token)
                .toString();
        //获取openId
        try {
            //json字符串
            String  body = Jsoup.connect(url).execute().body().substring(9);
            //转换为对象
            JSONObject jsonObject = JSONObject.parseObject(body.substring(0, body.length() - 3));
            //是否有异常
            Object error = jsonObject.get("error");
            if(error != null){
                log.warn("QQ登录获取openId失败{}",error);
                return null;
            }
            return (String) jsonObject.get("openid");

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    public Map<String, String> getUserInfo(String token,String openId){
        //获取头像信息
        String url = new StringBuffer().append("https://graph.qq.com/user/get_user_info")
                .append("?access_token=").append(token)
                .append("&oauth_consumer_key=").append(appId)
                .append("&&openid=").append(openId)
                .toString();
        try {
            //发出请求
            String  jsonString = Jsoup.connect(url).get().body().text();
            JSONObject parseObject = JSONObject.parseObject(jsonString);
            //是否出现异常
            Integer ret = (Integer)parseObject.get("ret");
            if(ret != 0) {
                log.warn("获取用户QQ信息失败{}",parseObject.get("msg"));
                return null;
            };
            Map<String,String> userInfo=new HashMap<String, String> ();
            userInfo.put(NICK_NAME_KEY, parseObject.get("nickname").toString());
            userInfo.put(GENDER_KEY, parseObject.get("gender").toString());
            //头像 figureurl_qq_2=QQ的100*100头像，figureurl_2=QQ 100&100空间头像，QQ头像不一定有，空间头像一定有
            Object avatar = parseObject.get("figureurl_qq_2");
            if(avatar == null || "".equals(avatar)){
                avatar=parseObject.get("figureurl_2");
            }
            userInfo.put(AVATAR_KEY,avatar.toString());
            return userInfo;
        } catch (IOException e) {
            log.error("获取用户信息失败{}",e);
            e.printStackTrace();
        }
        return null;
    }


    public UserAuths getUserAuths(String token,String openId){
        Map<String, String> userInfo = getUserInfo(token, openId);
        //构建对象
        return new UserAuths()
                //用户基本信息
                .setUser(new User()
                        .setUserNickName(userInfo.get("nickName"))
                        .setUserAvatar(userInfo.get("avatar"))
                        .setUserSex(userInfo.get("gender").equals("女")?0:1))
                //第三方登录账号密码信息统一使用唯一标识
                .setUserIdentifier(openId)
                .setUserCredential(openId);
    }
    /**
     * 解析字符串获取token信息
     * @param str
     * @return
     */
    private String parseStringGetToken(String str){
        return str.split("&")[0].split("=")[1];
    }




}
